package com.common.www.service.file;

import com.common.www.MyApplicationListener;
import org.springframework.boot.base.jpa.service.BaseService;
import com.common.www.bean.entity.file.FileCommon;
import com.common.www.bean.entity.file.enums.FileType;
import com.common.www.repository.file.FileRepository;
import com.common.www.utils.Base64Utils;
import com.common.www.utils.FileUtils;
import com.common.www.utils.ImageUtils;
import com.common.www.utils.TimeUtils;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.UUID;

import javax.imageio.ImageIO;

/**
 * Created by cwx183898 on 2017/12/14.
 */
@Service
@Transactional
public class FileService extends BaseService<FileCommon, Long> {
    private static final Log LOG = LogFactory.getLog(FileService.class);

    @Value("${spring.datasource.url}")
    private String mySqlPath;

    @Value("${server.servlet.context-path}")
    private String projectName;
    @Value("${server.port}")
    private String port;
    @Value("${wmp.upload.rootPath}")
    private String fileRootPath;
    @Value("${publicIpAddress}")
    private String publicIp;

    @Autowired
    @Qualifier("simpleRestTemplate")
    protected RestTemplate restTemplate;

    @Autowired
    private FileRepository repository;

    @Override
    public FileRepository getRepository() {
        return repository;
    }

    /**
     * 得到项目路径
     */
    public String getProjectPath() {
        String path = "http://" + getIp() + ":" + port + projectName;
        return path;
    }

    /**
     * 得到公网项目路径
     */
    public String getPublicProjectPath() {
        String path = "http://" + publicIp + projectName;
        return path;
    }

    /**
     * 得到公网项目路径
     */
    public static String getPublicProjectPath(String absPath) {
        String url = MyApplicationListener.publicProjectPath + absPath;
        return url;
    }

    public String getFileRootPath() {
        return fileRootPath;
    }

    public String getIp() {
        return mySqlPath.substring(mySqlPath.indexOf("jdbc:mysql://") + "jdbc:mysql://".length(),
                mySqlPath.indexOf(":", "jdbc:mysql://".length()));
//        return mySqlPath.substring(mySqlPath.indexOf("jdbc:mysql://") + "jdbc:mysql://".length(),
//                mySqlPath.indexOf(":8066"));
    }


    /**
     * 保存一个文件
     */
    private FileCommon saveFile(File file, String moduleName) {
        try {
            //存储文件对象记录
            FileCommon fileCommon = new FileCommon();
            fileCommon.setSrcName("");
            fileCommon.setAbsPath(file.getAbsolutePath().replace(fileRootPath, ""));
            fileCommon.setCreateUser("System");
            fileCommon.setDestName(file.getName());
            fileCommon.setModuleName(moduleName);
            fileCommon.setDownloadPath(getProjectPath() + "/" + fileCommon.getAbsPath());
            if (FileUtils.isImgFile(fileCommon.getDestName())) {
                fileCommon.setFileType("img");
                //获取上传图片的宽高
                InputStream is = new FileInputStream(file);
                BufferedImage bi = ImageIO.read(is);
                fileCommon.setWidth(bi.getWidth());
                fileCommon.setHeight(bi.getHeight());
            } else {
                fileCommon.setFileType("file");
            }
            fileCommon.setSize(file.length());
            fileCommon = save(fileCommon);

            return fileCommon;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 删除所有临时文件
     */
    public void deleteTempFiles() {
        System.out.println("临时文件删除开始");
        File file = new File(getFileRootPath());
        if (!file.exists()) {
            return;
        }
        File tempFileDir = new File(file.getAbsolutePath() + File.separator + "temp");
        if (!tempFileDir.exists()) {
            return;
        }
        File[] files = tempFileDir.listFiles();
        for (int i = 0; i < files.length; i++) {
            File file1 = files[i];

            if (!FileUtils.isInUse(file1) && System.currentTimeMillis() - file1.lastModified() > 24 * 60 * 60 * 1000) {
                file1.delete();
            }
        }
    }

    /**
     * 保存一个上传的文件
     *
     * @param gapDay 以日期为分割该模块下数据(每天一个文件夹)
     */
    public FileCommon saveFile(MultipartFile file, String moduleName, boolean gapDay, boolean isDestName) {
        try {
            String path = "";
//            String path = "http://localhost:18087/real_estate_app/";

            String srcFileName = file.getOriginalFilename();
//            System.out.println("上传原文件名：" + srcFileName);
            String destName;
            if (isDestName) {
                destName = UUID.randomUUID().toString().replaceAll("[-]", "") +
                        "." + FileUtils.getSuffix(srcFileName);
            } else {
                destName = srcFileName;
            }

            String dayDir = TimeUtils.getLocalDate(TimeUtils.YMD) + "";//一天一个文件夹
            String destPath;
            if (gapDay) {
                destPath = moduleName + "/" + dayDir + "/" + destName;
            } else {
                destPath = moduleName + "/" + destName;
            }

//            System.out.println("保存文件名：" + destFileName);
            path += destPath;
            String destFullPath = (fileRootPath + "/" + destPath).replaceAll("//", "/");
            File newFile = new File(destFullPath);
            if (!newFile.getParentFile().exists()) {
                newFile.getParentFile().mkdirs();
            }
            newFile.createNewFile();
            file.transferTo(newFile);

            //存储文件对象记录
            FileCommon fileCommon = new FileCommon();
            fileCommon.setSrcName(srcFileName);
            fileCommon.setAbsPath(destPath);
//            if (SecurityContextHolder.getContext().getAuthentication() != null)
//                fileCommon.setCreateUser(GlobalSessionUtils.getUserName());
            fileCommon.setDestName(destName);
            fileCommon.setModuleName(moduleName);
            fileCommon.setDownloadPath(getProjectPath() + fileCommon.getAbsPath());
            if (FileUtils.isImgFile(destName)) {
                fileCommon.setFileType("img");
                //获取上传图片的宽高
//                try {
//                    BufferedImage bi = ImageIO.read(file.getInputStream());
//                    fileCommon.setWidth(bi.getWidth());
//                    fileCommon.setHeight(bi.getHeight());
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
            } else {
                fileCommon.setFileType("file");
            }
            fileCommon.setSize(file.getSize());
            fileCommon = save(fileCommon);

            return fileCommon;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 保存一个上传的文件
     *
     * @param moduleName 当前模块名
     */
    public FileCommon saveFile(String base64, String moduleName) throws Exception {

        String renName = UUID.randomUUID().toString().replaceAll("[-]", "") +
                "." + Base64Utils.getBaseStrSuffix(base64);
        String dayDir = TimeUtils.getLocalDate(TimeUtils.YMD) + "";//一天一个文件夹
        String destPath = moduleName + '/' + dayDir + '/' + renName;
        String tmpFilePath = MyApplicationListener.fileRootPath
                + '/' + destPath;

        File file = new File(tmpFilePath);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        file.createNewFile();

        //去掉base64前缀
        if (base64.contains(",")) {
            base64 = base64.substring(base64.indexOf(",") + 1, base64.length());
        }
        ImageUtils.base64ToImage(base64, tmpFilePath);

        //存储文件对象记录
        FileCommon fileCommon = new FileCommon();
        fileCommon.setSrcName("base64");
        fileCommon.setAbsPath(destPath);

        fileCommon.setDestName(renName);
        fileCommon.setModuleName(moduleName);
        fileCommon.setDownloadPath(getPublicProjectPath(fileCommon.getAbsPath()));


        if (FileUtils.isImgFile(renName)) {
            fileCommon.setType(FileType.IMG.getValue());
            //获取上传图片的宽高
            try {
                InputStream input = new FileInputStream(file);
                BufferedImage bi = ImageIO.read(input);
                fileCommon.setWidth(bi.getWidth());
                fileCommon.setHeight(bi.getHeight());
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (FileUtils.isGifFile(renName)) {
            fileCommon.setType(FileType.GIF.getValue());
            //获取上传图片的宽高
//            try {
//                InputStream input = new FileInputStream(file);
//                GifDecoder.GifImage gif = GifDecoder.read(input);
////                    BufferedImage bi = ImageIO.read(readInputStream(inputStream));
//                fileCommon.setWidth(gif.getWidth());
//                fileCommon.setHeight(gif.getHeight());
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
        } else if (FileUtils.isVideoFile(renName)) {
            fileCommon.setType(FileType.VIDEO.getValue());
        } else {
            fileCommon.setType(FileType.OTHER.getValue());
        }
        fileCommon.setSize(file.length());
        fileCommon.setSuffix(FileUtils.getSuffix(renName));

        fileCommon = save(fileCommon);

        if (fileCommon == null) {
            throw new Exception("保存文件失败");
        }
        return fileCommon;
    }


    /**
     * 保存一个上传的文件
     *
     * @param gapDay 以日期为分割该模块下数据(每天一个文件夹)
     */
    public FileCommon saveNetFile(String fileUrl, String suffix, String moduleName, boolean gapDay, boolean isDestName) {
        try {
            String path = "";


            String srcFileName = FileUtils.getFileNameByPath(fileUrl);
//            System.out.println("上传原文件名：" + srcFileName);
            String destName;
            if (isDestName) {
                if (suffix != null) {
                    destName = UUID.randomUUID().toString().replaceAll("[-]", "") +
                            "." + suffix;
                } else {
                    destName = UUID.randomUUID().toString().replaceAll("[-]", "") +
                            "." + FileUtils.getSuffix(srcFileName);
                }

            } else {
                destName = srcFileName;
            }

            String dayDir = TimeUtils.getLocalDate(TimeUtils.YMD) + "";//一天一个文件夹
            String destPath;
            if (gapDay) {
                destPath = moduleName + "/" + dayDir + "/" + destName;
            } else {
                destPath = moduleName + "/" + destName;
            }

//            System.out.println("保存文件名：" + destFileName);
            path += destPath;
            String destFullPath = (fileRootPath + "/" + destPath).replaceAll("//", "/");
            File newFile = new File(destFullPath);
            if (!newFile.getParentFile().exists()) {
                newFile.getParentFile().mkdirs();
            }
//            newFile.createNewFile();

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            HttpEntity<String> entity = new HttpEntity<>(headers);
            ResponseEntity<byte[]> response = restTemplate.exchange(fileUrl, HttpMethod.GET, entity, byte[].class);
            FileOutputStream fos = new FileOutputStream(new File(newFile.getAbsolutePath()));
            fos.write(response.getBody());
            fos.close();


            //存储文件对象记录
            FileCommon fileCommon = new FileCommon();
            fileCommon.setSrcName(srcFileName);
            fileCommon.setAbsPath(destPath);
//            if (SecurityContextHolder.getContext().getAuthentication() != null)
//                fileCommon.setCreateUser(GlobalSessionUtils.getUserName());
            fileCommon.setDestName(destName);
            fileCommon.setModuleName(moduleName);
            fileCommon.setDownloadPath(getProjectPath() + fileCommon.getAbsPath());
            if (FileUtils.isImgFile(destName)) {
                fileCommon.setFileType("img");
                //获取上传图片的宽高
//                try {
//                    BufferedImage bi = ImageIO.read(file.getInputStream());
//                    fileCommon.setWidth(bi.getWidth());
//                    fileCommon.setHeight(bi.getHeight());
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
            } else {
                fileCommon.setFileType("file");
            }
            fileCommon.setSize(newFile.length());
            fileCommon = save(fileCommon);

            return fileCommon;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

}
